package com.jzo2o.foundations.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import com.jzo2o.foundations.service.HomeService;
import com.jzo2o.foundations.service.IRegionService;
import com.jzo2o.foundations.service.IServeItemService;
import com.jzo2o.foundations.service.IServeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 用户端首页业务处理实现类
 *
 * @Author mr.wu
 * @Date 2024-12-5 16:53
 */
@Service
public class HomeServiceImpl implements HomeService {

    @Autowired
    private ServeMapper serveMapper;


    /**
     * 根据区域查询服务类型列表(前2个)和对应的服务项列表（前4个）
     *
     * @param regionId
     * @return
     */
    @Caching(cacheable = {
            //当返回的列表有元素时，永久不过期
            @Cacheable(value = RedisConstants.CacheName.SERVE_ICON, unless = "#result.size()==0",key = "#regionId", cacheManager = RedisConstants.CacheManager.FOREVER),
            //当返回的列表没元素时，30分钟过期
            @Cacheable(value = RedisConstants.CacheName.SERVE_ICON, unless = "#result.size()!=0", key = "#regionId", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES)
    })
    @Override
    public List<ServeCategoryResDTO> queryCateAndServeList(Long regionId) {

        //1. 根据区域ID查询类型列表和服务项列表
        List<ServeCategoryResDTO> serveCategoryResDTOList = serveMapper.queryCateAndServeList(regionId);
        if(CollUtils.isEmpty(serveCategoryResDTOList)){
            return CollUtils.emptyList();
        }

        //2. 设置只取前2个服务类型列表
        int cateSize = serveCategoryResDTOList.size() >= 2 ? 2: serveCategoryResDTOList.size();
        //serveCategoryResDTOList = serveCategoryResDTOList.stream().limit(cateSize).collect(Collectors.toList());
        serveCategoryResDTOList = new ArrayList<>(serveCategoryResDTOList.subList(0,cateSize));

        //3. 设置在每个服务类型下只取前4个服务项列表
        for (ServeCategoryResDTO cate : serveCategoryResDTOList) {

            List<ServeSimpleResDTO> serveList = cate.getServeResDTOList();
            int serveSize = serveList.size()>=4 ? 4 : serveList.size();
            cate.setServeResDTOList(new ArrayList<>(serveList.subList(0,serveSize)));
        }

        return serveCategoryResDTOList;
    }



    @Autowired
    private IRegionService regionService;

    @Autowired
    private IServeService serveService;

    @Autowired
    private IServeItemService serveItemService;


    /**
     * 根据区域id查询热门服务列表
     *
     * @param regionId 区域id
     * @return 服务列表
     */
    @Override
    @Caching(
            cacheable = {
                    //result为null时,属于缓存穿透情况，缓存时间30分钟
                    @Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId",
                            unless = "#result.size() != 0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    //result不为null时,永久缓存
                    @Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId",
                            unless = "#result.size() == 0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    public List<ServeAggregationSimpleResDTO> queryHotServeListByRegionIdCache(Long regionId) {
        //1.校验当前城市是否为启用状态
        Region region = regionService.getById(regionId);
        if (ObjectUtil.equal(FoundationStatusEnum.DISABLE.getStatus(), region.getActiveStatus())) {
            return Collections.emptyList();
        }

        //2.根据城市编码查询热门服务
        List<ServeAggregationSimpleResDTO> list = serveService.findHotServeListByRegionId(regionId);
        if (ObjectUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list;
    }

    /**
     * 根据区域id查询已开通的服务类型
     * @param regionId 区域id
     * @return 已开通的服务类型
     */
    @Override
    @Caching(
            cacheable = {
                    //result为null时,属于缓存穿透情况，缓存时间30分钟
                    @Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId",
                            unless = "#result.size() != 0", cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),
                    //result不为null时,永久缓存
                    @Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId",
                            unless = "#result.size() == 0", cacheManager = RedisConstants.CacheManager.FOREVER)
            }
    )
    public List<ServeAggregationTypeSimpleResDTO> queryServeTypeListByRegionIdCache(Long regionId) {
        //1.校验当前城市是否为启用状态
        Region region = regionService.getById(regionId);
        if (ObjectUtil.equal(FoundationStatusEnum.DISABLE.getStatus(), region.getActiveStatus())) {
            return Collections.emptyList();
        }

        //2.根据城市编码查询服务对应的服务分类
        List<ServeAggregationTypeSimpleResDTO> list = serveService.findServeTypeListByRegionId(regionId);
        if (ObjectUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list;
    }


    /**
     * 根据id查询服务详情
     *
     * @param id
     * @return
     */
    @Override
    public ServeAggregationSimpleResDTO queryDetailById(Long id) {
        //1.查询服务信息
        Serve serve = serveService.getByIdCache(id);

        //2.查询服务项信息
        ServeItem serveItem = serveItemService.getByIdCache(serve.getServeItemId());

        //3.封装数据
        ServeAggregationSimpleResDTO serveAggregationSimpleResDTO = BeanUtil.toBean(serve, ServeAggregationSimpleResDTO.class);
        serveAggregationSimpleResDTO.setServeItemName(serveItem.getName());
        serveAggregationSimpleResDTO.setServeItemImg(serveItem.getImg());
        serveAggregationSimpleResDTO.setDetailImg(serveItem.getDetailImg());
        serveAggregationSimpleResDTO.setUnit(serveItem.getUnit());
        return serveAggregationSimpleResDTO;
    }
}
